<template>
  <div class="photo-wall-container">
    <div class="box" ref="box" @pointerdown="startDrag" :style="{ transform: `rotateX(${-tY}deg) rotateY(${tX}deg)` }">
      <div v-for="(row, rowIndex) in processedRows" :key="rowIndex" class="box-imgs" :ref="el => setRowRef(el, rowIndex)"
           :style="{ animationPlayState: autoRotateState }">
        <img v-for="(img, imgIndex) in row" :key="imgIndex" :src="img" :alt="`图片${rowIndex * row.length + imgIndex + 1}`"
             :style="getImgStyle(imgIndex, row.length)" @click="showModal(img)">
      </div>
    </div>

    <div class="modal" :class="{ show: showModalState }" @click.self="closeModal">
      <span class="close" @click="closeModal">&times;</span>
      <img class="modal-content" :src="currentImg" ref="modalImg">
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, watch } from 'vue'

const props = defineProps({
  // 图片数据，二维数组形式 [[第一行图片], [第二行图片], ...]
  images: {
    type: Array,
    default: () => []
  },
  // 自动旋转
  autoRotate: {
    type: Boolean,
    default: true
  },
  // 初始X轴旋转角度
  initialXAngle: {
    type: Number,
    default: 0
  },
  // 初始Y轴旋转角度
  initialYAngle: {
    type: Number,
    default: 30
  },
  // 初始半径
  initialRadius: {
    type: Number,
    default: 560
  },
  // 图片宽度
  imgWidth: {
    type: [String, Number],
    default: '120px'
  },
  // 图片高度
  imgHeight: {
    type: [String, Number],
    default: '140px'
  },
  // 行间距
  rowGap: {
    type: [String, Number],
    default: '6px'
  }
})

const emit = defineEmits(['img-click'])

// 响应式状态
const radius = ref(props.initialRadius)
const tX = ref(props.initialXAngle)
const tY = ref(props.initialYAngle)
const autoRotateState = ref(props.autoRotate)
const showModalState = ref(false)
const currentImg = ref('')
const box = ref(null)
const rowRefs = reactive([])

// 处理图片数据，确保是二维数组
const processedRows = computed(() => {
  // 如果传入的是二维数组，直接使用
  if (Array.isArray(props.images[0])) {
    return props.images
  }
  // 如果是一维数组，按每行图片数量分组
  const images = props.images || []
  const perRow = Math.max(1, Math.floor(images.length / 3)) // 默认每行大约1/3总图片数
  const result = []
  for (let i = 0; i < images.length; i += perRow) {
    result.push(images.slice(i, i + perRow))
  }
  return result
})

// 自动旋转状态
// const autoRotateState = computed(() => autoRotateState.value ? 'running' : 'paused')

// 设置每排元素的引用
const setRowRef = (el, index) => {
  if (el) rowRefs[index] = el
}

// 计算图片位置
const getImgStyle = (index, total) => {
  return {
    transform: `rotateY(${index * (360 / total)}deg) translateZ(${radius.value}px)`
  }
}

// 更新所有图片位置
const updateAllImages = () => {
  rowRefs.forEach((rowEl, rowIndex) => {
    const imgs = rowEl?.querySelectorAll('img') || []
    imgs.forEach((img, imgIndex) => {
      img.style.transform = `rotateY(${imgIndex * (360 / imgs.length)}deg) translateZ(${radius.value}px)`
    })
  })
}

// 拖拽相关变量
let startX, startY, endX, endY, desX = 0, desY = 0
let dragInterval = null

// 开始拖拽
const startDrag = (e) => {
  e.preventDefault()
  clearInterval(dragInterval)
  startX = e.clientX
  startY = e.clientY
  autoRotateState.value = false

  const onPointerMove = (e) => {
    endX = e.clientX
    endY = e.clientY
    desX = endX - startX
    desY = endY - startY
    tX.value += desX * 0.1
    tY.value += desY * 0.1

    // 限制X轴旋转角度
    if (tY.value > 180) tY.value = 180
    if (tY.value < 0) tY.value = 0

    startX = endX
    startY = endY
  }

  const onPointerUp = () => {
    // 惯性滑动效果
    dragInterval = setInterval(() => {
      desX *= 0.95
      desY *= 0.95

      if (Math.abs(desX) < 0.5 && Math.abs(desY) < 0.5) {
        clearInterval(dragInterval)
        autoRotateState.value = props.autoRotate
        return
      }

      tX.value += desX * 0.1
      tY.value += desY * 0.1

      // 限制X轴旋转角度
      if (tY.value > 180) tY.value = 180
      if (tY.value < 0) tY.value = 0
    }, 16)

    document.removeEventListener('pointermove', onPointerMove)
    document.removeEventListener('pointerup', onPointerUp)
  }

  document.addEventListener('pointermove', onPointerMove)
  document.addEventListener('pointerup', onPointerUp)
}

// 鼠标滚轮缩放
const handleWheel = (e) => {
  e.preventDefault()
  const delta = e.deltaY > 0 ? -20 : 20
  radius.value += delta

  // 限制半径范围
  radius.value = Math.max(300, Math.min(1000, radius.value))
  updateAllImages()
}

// 显示模态框
const showModal = (img) => {
  currentImg.value = img
  showModalState.value = true
  autoRotateState.value = false
  emit('img-click', img)
}

// 关闭模态框
const closeModal = () => {
  showModalState.value = false
  autoRotateState.value = props.autoRotate
}

// 监听props变化
watch(() => props.autoRotate, (newVal) => {
  autoRotateState.value = newVal
})

watch(() => props.initialRadius, (newVal) => {
  radius.value = newVal
  updateAllImages()
})

// 初始化
onMounted(() => {
  document.addEventListener('wheel', handleWheel, {passive: false})
  updateAllImages()
})
</script>

<style scoped lang="less">
.photo-wall-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  background-color: #000;
  perspective: 500px;
  perspective-origin: center;
}

.box {
  transform-style: preserve-3d;
  height: 100%;
}

.box-imgs {
  transform-style: preserve-3d;
  position: relative;
  margin: auto;
  width: v-bind('typeof props.imgWidth === "number" ? `${props.imgWidth}px` : props.imgWidth');
  height: v-bind('typeof props.imgHeight === "number" ? `${props.imgHeight}px` : props.imgHeight');
  animation: autoRotate 200s infinite linear;
}

.box-imgs:not(:first-child) {
  margin-top: v-bind('typeof props.rowGap === "number" ? `${props.rowGap}px` : props.rowGap');
}

.box-imgs img {
  transform-style: preserve-3d;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 4px;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
  cursor: pointer;
  transition: transform 0.3s ease;
}

.box-imgs img:hover {
  transform: scale(1.05);
}

.box-imgs:last-child img {
  -webkit-box-reflect: below 10px linear-gradient(transparent, transparent, #0005);
}

@keyframes autoRotate {
  from {
    transform: rotateY(0deg);
  }

  to {
    transform: rotateY(360deg);
  }
}

.modal {
  display: none;
  position: fixed;
  z-index: 1000;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.9);
  justify-content: center;
  align-items: center;
}

.modal.show {
  display: flex;
}

.modal-content {
  max-width: 80%;
  max-height: 80%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
}

.close {
  position: absolute;
  top: 20px;
  right: 30px;
  color: #fff;
  font-size: 40px;
  font-weight: bold;
  cursor: pointer;
  transition: 0.3s;
}

.close:hover,
.close:focus {
  color: #bbb;
  text-decoration: none;
}
</style>